import { Button, Card, Form, Modal, Select, Tooltip } from 'antd';
import { FC } from 'react';

import { ApiBody, post } from '@/api';
import { Category } from '@/components/base/Category';
import { SelectAll } from '@/components/base/SelectAll';
import { Table } from '@/components/base/Table';
import { VariableValueField } from '@/components/base/ValueOfType';
import { NODE_TYPE } from '@/constants/config';
import { useCurrentNode } from '@/hooks/useCurrentNode';

import { Rules } from '../../Rules';
import { VariablesTable } from '../../VariablesTable';
import { useDataSource } from './data';

export const DataLoadConfig: FC = memo(() => {
  const { getNodeDataFor, setNodeDataFor, variable2Options } = useCurrentNode<NODE_TYPE.DATA_LOAD>();
  const [form] = Form.useForm<ApiBody<'post', '/ds/execute'>>();
  const { dataSetOptions, colsVariables, tablesOptions, getTables, rightVariables, getColsOptions } = useDataSource();
  const [testOpen, setTestOpen] = useState(false);
  const data = getNodeDataFor();
  const [testRes, setTestRes] = useState<any[]>([]);
  const [dataSource, setDataSource] = useState<VariableItem[]>([]);
  const rightVariableNames = useRef<string[]>([]);

  const [tempAllPrivateVariables, setTempAllPrivateVariables] = useState<string[]>([]);
  const [testLoading, setTestLoading] = useState(false);

  const testStart = useCallback(() => {
    const data = form.getFieldsValue();
    const testParams = {} as any;
    rightVariableNames.current.forEach((varName, index) => {
      testParams[varName!] = tempAllPrivateVariables[index];
    });
    setTestLoading(true);
    post('/ds/execute', {
      data: {
        dataSource: data.dataSource,
        tableName: getNodeDataFor()?.tableName,
        columns: data.columns,
        criteria: data.criteria,
        params: testParams
      }
    })
      .then((res) => {
        setTestRes(res || []);
      })
      .finally(() => {
        setTestLoading(false);
      });
  }, [form, getNodeDataFor, tempAllPrivateVariables]);

  const resColumns = useMemo(() => {
    return colsVariables.map((item) => ({
      title: item.varLabel,
      dataIndex: item.varName,
      width: '120px',
      render(value: any) {
        if (typeof value === 'object') {
          return JSON.stringify(value);
        }
        return (
          <Tooltip title={<div className="max-h-400 overflow-y-auto max-w-400">{value}</div>}>
            <div className="max-w-120 truncate">{value}</div>
          </Tooltip>
        );
      }
    }));
  }, [colsVariables]);

  const openTestModal = () => {
    setTestOpen(true);
    const criteria = form.getFieldValue('criteria');
    rightVariableNames.current = [];
    function traverseCondition(condition: any) {
      if (condition.type === 'Criterion') {
        if (condition.rightType === 'VARIABLE' && condition.right) {
          rightVariableNames.current.push(condition.right);
        }
      } else if (condition.type === 'Criteria' && condition.conditions) {
        for (const subCondition of condition.conditions) {
          traverseCondition(subCondition);
        }
      }
    }
    traverseCondition(criteria);
    const data = rightVariableNames.current.map((varName) => {
      return rightVariables.find((vars) => vars.varName === varName)!;
    });
    setDataSource(data);
  };

  useEffect(() => {
    form.setFieldsValue(data!);
  }, [data, form, getNodeDataFor]);

  return (
    <Card size="small" title="数据加载配置" className="data-load-config mt-12">
      <Form
        form={form}
        onValuesChange={(_, value) => {
          setNodeDataFor({
            ...data,
            ...value
          });
        }}
        layout="vertical">
        <Form.Item name="dataSource" required label="数据源">
          <Select
            allowClear
            showSearch
            placeholder="请选择数据源"
            onChange={(dataSource = null) => {
              setNodeDataFor({
                ...data,
                dataSource,
                tableName: undefined,
                columns: []
              });
              getTables(dataSource);
            }}
            options={dataSetOptions}
          />
        </Form.Item>
        <Form.Item name="tableName" required label="数据集">
          <Select
            allowClear
            showSearch
            placeholder="请选择数据集"
            onChange={(tableName = null) => {
              setNodeDataFor({
                ...data,
                tableName,
                columns: []
              });
              getColsOptions();
            }}
            options={tablesOptions}
          />
        </Form.Item>
        <Form.Item required name="columns" label="查询列">
          <SelectAll placeholder="请选择查询列" mode="multiple" allowClear showSearch options={variable2Options(colsVariables)} />
        </Form.Item>
        <Form.Item required name="criteria" label="条件">
          <Rules leftVariables={colsVariables} rightVariables={rightVariables} />
        </Form.Item>
      </Form>
      <div className="flex gap-12">
        <Button type="primary" onClick={openTestModal}>
          测试数据集
        </Button>
        <Button
          type="default"
          onClick={() => {
            form.resetFields();
            setNodeDataFor({
              ...data,
              dataSource: '',
              tableName: '',
              columns: [],
              criteria: undefined
            });
          }}>
          重置数据集
        </Button>
      </div>
      <Modal
        onOk={testStart}
        confirmLoading={testLoading}
        okText="测试"
        cancelText="关闭"
        destroyOnClose
        width={1200}
        onCancel={() => {
          setTestOpen(false);
          setDataSource([]);
          setTestRes([]);
          setTestLoading(false);
          setTempAllPrivateVariables([]);
        }}
        open={testOpen}
        title="测试数据集">
        <VariablesTable
          dataSource={dataSource}
          title="参数"
          actions={{
            title: '值',
            key: 'action',
            render: (record, __, index) => {
              return (
                <VariableValueField
                  varType={record.varType!}
                  options={record.options || []}
                  value={tempAllPrivateVariables[index] || record.initValue}
                  onChange={(value) => {
                    tempAllPrivateVariables[index] = value;
                    setTempAllPrivateVariables([...tempAllPrivateVariables]);
                  }}
                />
              );
            }
          }}
        />
        {!!testRes.length && (
          <>
            <Category className="py-12">结果预览</Category>
            <Table columns={resColumns} pagination={false} rowKey="id" dataSource={testRes} />
          </>
        )}
      </Modal>
    </Card>
  );
});
